package week_3.experiment;

import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;

import static week_3.experiment.SecondExperiment.selectionSort;

//使用选择排序法根据数值大小对链表进行排序。
public class ThirdExperiment {
    public static void main(String[] args) throws IOException {
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入一些整数，这些整数是你学号中依次取出的两位数以及+\n\t+今天的时间（例如：2018/10/1,16:23:49就是数字20,17,23,1，16,23,49）");
        String sentence =scan.nextLine();
        int[] number = new int[100];
        String[] numbers = sentence.split(",");
        for(int a = 0;a<numbers.length;a++)
        {
            number[a] = Integer.parseInt(numbers[a]);
        }
        FirstLinkedlist Head = new FirstLinkedlist(number[0]);
        int nLixinyu = 1;
        for(int a=1; a < numbers.length;a++)
        {
            FirstLinkedlist node = new FirstLinkedlist(number[a]);
            InsertNode(Head,node);
            nLixinyu++;
        }

        //打印链表元素。
        System.out.println("链表元素是：");
        PrintLinkedlist(Head);
        System.out.println();
        System.out.println("元素总数为"+nLixinyu);

        //磁盘读取一个文件， 这个文件有两个数字
        File file = new File("sort.txt");
        Reader reader = new FileReader(file);
        BufferedReader bufferedReader = new BufferedReader(reader);
        StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine());
        int  num = stringTokenizer.countTokens();
        int[] counts = new int[num];
        int a=0;
        while(stringTokenizer.hasMoreTokens()){
            counts[a]=Integer.parseInt(stringTokenizer.nextToken());
            a++;
        }
        int firstnumber =counts[0];//从文件中读出的第一个数
        int secondnumber = counts[1];//从文件中读出的第二个数

        /*	从文件中读入数字1，  插入到链表第 5 位，并打印所有数字，和元素的总数。 保留这个链表，继续下面的操作。*/
        FirstLinkedlist node1 = new FirstLinkedlist(firstnumber);
        FirstLinkedlist temp = Head;
        for(int b = 0;b<5;b++)
        {
            temp=temp.next;
        }
        InsertNode(Head,temp,node1);
        nLixinyu++;
        System.out.println("插入从文件读出第一个元素后的链表为：" );
        PrintLinkedlist(Head);
        System.out.println("链表的个数变为："+nLixinyu);
        //从文件中读入数字2， 插入到链表第 0 位，并打印所有数字，和元素的总数。 保留这个链表，并继续下面的操作。
        FirstLinkedlist node2 = new FirstLinkedlist(secondnumber);
        InsertNode1(Head,node2);
        nLixinyu++;
        System.out.println("插入从文件读出第二个元素后的链表为：");
        PrintLinkedlist(node2);
        System.out.println("链表的个数变为："+nLixinyu);
        //从链表中删除刚才的数字1.  并打印所有数字和元素的总数。
        FirstLinkedlist node3 = Head;
        while(node3.number!=2017)
        {
            node3=node3.next;
        }
        Deletenode(Head,node3);
        nLixinyu--;
        System.out.println("删除插入的第一个元素后链表为：");
        PrintLinkedlist(node2);
        System.out.println("链表的个数变为："+nLixinyu);
        //使用选择排序法根据数值大小对链表进行排序。
        System.out.println("用选择排序后的链表：");
        selectionSort(node2);

    }
    //链表的输出方法。
    public static void PrintLinkedlist(FirstLinkedlist Head) {
        FirstLinkedlist node = Head;//链表的头不能动。
        while (node != null) {
            System.out.print(" " + node.number);
            node = node.next;
        }
    }

    //头插法的方法。
    public static void InsertNode1(FirstLinkedlist Head, FirstLinkedlist node) {
        node.next = Head;
        Head = node;
        System.out.print(Head .number+" ");
    }


    //尾插法的方法。
    public static void InsertNode(FirstLinkedlist Head, FirstLinkedlist node) {
        FirstLinkedlist temp = Head;
        //遍历链表，找到链表末尾。
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = node;
    }

    //链表的中间插入。
    public static void InsertNode(FirstLinkedlist Head, FirstLinkedlist node1, FirstLinkedlist node2) {
        FirstLinkedlist point = Head;
        while ((point.number != node1.number) & point != null) {
            point = point.next;
        }
        if (point.number == node1.number) {
            node2.next = point.next;
            point.next = node2;
        }
    }

    //链表的删除方法。
    public static void Deletenode(FirstLinkedlist Head, FirstLinkedlist node) {//这里的node要指向需要删除对象的前一个节点。
        FirstLinkedlist prenode = Head, currentnode = Head;
        while (prenode != null) {
            if (currentnode != node) {
                prenode = currentnode;
                currentnode = currentnode.next;
            } else {
                break;
            }
        }
        prenode.next = currentnode.next;

    }

    //链表的选择排序法。
    public static FirstLinkedlist selectionSort(FirstLinkedlist Head) {
        //记录每次循环的最小值
        int temp ;
        FirstLinkedlist curNode = Head;
        while (curNode != null) {
            /**
             * 内重循环从当前节点的下一个节点循环到尾节点，
             * 找到和外重循环的值比较最小的那个，然后与外重循环进行交换
             */
            FirstLinkedlist nextNode = curNode.next;
            while (nextNode != null) {
                //比外重循环的小值放到前面
                if (nextNode.number < curNode.number) {
                    temp = nextNode.number;
                    nextNode.number = curNode.number;
                    curNode.number = temp;
                }
                nextNode = nextNode.next;
            }
            curNode = curNode.next;
            PrintLinkedlist(Head);
            System.out.println();
        }
        return Head;
    }
}
